package com.app.signing.view.signin

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.view.View
import com.amap.api.maps.AMap
import com.amap.api.maps.AMap.OnMapLoadedListener
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.Circle
import com.amap.api.maps.model.CircleOptions
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.Marker
import com.amap.api.maps.model.MarkerOptions
import com.app.signing.R
import com.app.signing.app.loge
import com.app.signing.app.logi
import com.app.signing.data.DbManager
import com.app.signing.data.SpManager
import com.app.signing.data.bean.SeatDataDb
import com.app.signing.data.bean.SigningSetting
import com.app.signing.utils.LocationResult
import com.app.signing.utils.LocationService
import com.app.signing.utils.TimerUtil
import com.app.signing.utils.TimerUtil.TimeCallback
import com.app.signing.utils.Utils
import com.app.signing.view.base.BaseActivity
import kotlinx.android.synthetic.main.activity_sign_in.bt_sign_in_start
import kotlinx.android.synthetic.main.activity_sign_in.ll_sign_in_time
import kotlinx.android.synthetic.main.activity_sign_in.map_sign_in
import kotlinx.android.synthetic.main.layout_signing_time.bt_sign_in_end
import kotlinx.android.synthetic.main.layout_signing_time.text_sign_in_time

/**
 * 定位实现
 */
class SignInActivity : BaseActivity(), TimeCallback, OnMapLoadedListener {

    companion object {
        const val RECEIVER_LOCATION_ACTION = "location_in_background"
        const val RECEIVER_SIGNING_END_ACTION = "com.app.signing.sign_in_end"
        private const val ROOM_ID_KEY = "ROOM_ID_KEY"
        private const val ROOM_SEAT_KEY = "ROOM_SEAT_KEY"

        fun start(
            context: Context,
            roomId: String,
            seatId: String
        ) {
            val intent = Intent(context, SignInActivity::class.java)
            val bundle = Bundle()
            bundle.putString(ROOM_ID_KEY, roomId)
            bundle.putString(ROOM_SEAT_KEY, seatId)
            intent.putExtras(bundle)
            context.startActivity(intent)
        }
    }

    /**
     * 签到记录ID
     */
    private var signingId = -1L

    private lateinit var signingSetting: SigningSetting

    private lateinit var mapControl: AMap

    private lateinit var locationCircle: Circle

    private var roomId: String = ""

    private var seatId: String = ""

    private var timeUtils: TimerUtil? = null

    private var locationMarker: Marker? = null

    override fun getLayoutId(): Int {
        return R.layout.activity_sign_in
    }

    override fun initData() {
        // 检查是否设置签到范围
        signingSetting = SpManager.INSTANCE.readSigningSetting()
        if (signingSetting.latitude == 0.0 || signingSetting.longitude == 0.0) {
            showToast("未设置签到范围，请先登录管理员设置签到范围")
            finish()
            return
        }
        // 注册定位结果回调
        val intentFilter = IntentFilter()
        intentFilter.addAction(RECEIVER_LOCATION_ACTION)
        registerReceiver(locationChangeBroadcastReceiver, intentFilter)
        // 查询是否有未结束的签到记录
        val signingId = SpManager.INSTANCE.readSigningDataId()
        this.signingId = signingId
        // 查询座位
        val bundle = intent.extras
        roomId = bundle.getString(ROOM_ID_KEY)
        seatId = bundle.getString(ROOM_SEAT_KEY)
    }

    override fun initView(savedInstanceState: Bundle?) {
        if (signingId == -1L) {
            preSignInView()
        } else {
            revSigInView()
        }
        initMapView(savedInstanceState)
    }

    override fun onResume() {
        super.onResume()
        map_sign_in.onResume()
        startLocationService()
    }

    override fun onPause() {
        super.onPause()
        map_sign_in.onPause()
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        map_sign_in.onSaveInstanceState(outState)
    }

    override fun onDestroy() {
        unregisterReceiver(locationChangeBroadcastReceiver)
        unregisterReceiver(endChangeReceiver)
        super.onDestroy()
        timeUtils?.stop()
        map_sign_in.onDestroy()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        map_sign_in.onLowMemory()
    }

    override fun timeChange(time: String?) {
        runOnUiThread {
            time?.let {
                text_sign_in_time.text = time
            }
        }
    }

    override fun onMapLoaded() {
        addSigningMarker(mapControl.cameraPosition.target)
    }

    private fun initMapView(savedInstanceState: Bundle?) {
        map_sign_in.onCreate(savedInstanceState)
        mapControl = map_sign_in.map
        mapControl.uiSettings.isZoomControlsEnabled = false
        mapControl.setOnMapLoadedListener(this)
        // 画出签到范围
        locationCircle = mapControl.addCircle(
            CircleOptions().center(
                LatLng(signingSetting.latitude, signingSetting.longitude)
            ).radius(signingSetting.radius).strokeWidth(5f)
        )
    }

    /**
     * 显示当前的定位点
     */
    private fun addSigningMarker(latLng: LatLng) {
        val screenPosition = mapControl.projection.toScreenLocation(latLng)
        locationMarker?.destroy()
        locationMarker = mapControl.addMarker(
            MarkerOptions().anchor(0.5f, 0.5f).icon(
                BitmapDescriptorFactory.fromResource(R.drawable.purple_pin)
            )
        )
        locationMarker?.setPositionByPixels(screenPosition.x, screenPosition.y)
    }

    /**
     * 准备签到
     */
    private fun preSignInView() {
        ll_sign_in_time.visibility = View.GONE
        bt_sign_in_start.visibility = View.VISIBLE
        bt_sign_in_start.setOnClickListener {
            // 签到,当前定位位置判断
            if (!locationCircle.contains(mapControl.cameraPosition.target)) {
                showToast("位置已超出签到范围")
                return@setOnClickListener
            }
            // 创建签到记录
            signingId = DbManager.INSTANCE.createSigning()
            SpManager.INSTANCE.saveSigningDataId(signingId)
            // 创建占座的记录
            val userId = SpManager.INSTANCE.readLoginUserId()
            DbManager.INSTANCE.saveSeat(
                SeatDataDb(
                    roomId = roomId, seatId = seatId, userId = userId,
                    signingId = signingId, doing = true
                )
            )
            // 切换到计时页面
            revSigInView()
            // 开始计时
            val data = DbManager.INSTANCE.loadSigning(signingId)
            data?.let {
                timeUtils = TimerUtil(it.studyStartTime, this)
                timeUtils!!.start()
            }
        }
    }

    /**
     * 结束签到
     */
    private fun revSigInView() {
        val filter = IntentFilter()
        filter.addAction(RECEIVER_SIGNING_END_ACTION)
        registerReceiver(endChangeReceiver, filter)
        ll_sign_in_time.visibility = View.VISIBLE
        bt_sign_in_start.visibility = View.GONE
        val data = DbManager.INSTANCE.loadSigning(signingId)
        data?.let {
            timeUtils = TimerUtil(it.studyStartTime, this)
            timeUtils!!.start()
        }
        bt_sign_in_end.setOnClickListener {
            // 停止计时
            timeUtils?.stop()
            // 页面关闭
            finish()
            // 删除及结束保存的相关数据
            DbManager.INSTANCE.finishSigning(signingId)
            SpManager.INSTANCE.deleteSigningDataId()
            DbManager.INSTANCE.finishSeat(signingId)
        }
    }

    /**
     * 开始定位服务
     */
    private fun startLocationService() {
        applicationContext.startService(Intent(this, LocationService::class.java))
    }

    /**
     * 关闭服务
     * 先关闭守护进程，再关闭定位服务
     */
    private fun stopLocationService() {
        sendBroadcast(Utils.getCloseBroadcastIntent())
    }

    private val locationChangeBroadcastReceiver = object : BroadcastReceiver() {

        override fun onReceive(
            context: Context,
            intent: Intent
        ) {
            val action = intent.action
            if (action == RECEIVER_LOCATION_ACTION) {
                val locationResult = intent.getParcelableExtra<LocationResult>("result")
                if (locationResult.errorCode == 0) {
                    mapControl.moveCamera(
                        CameraUpdateFactory.newLatLngZoom(
                            LatLng(locationResult.latitude, locationResult.longitude), 16f
                        )
                    )
                    "定位结果：latitude-${locationResult.latitude},longitude-${locationResult.longitude}".logi()
                } else {
                    showToast("定位失败：${locationResult.errorCode}")
                    "定位：errorCode:${locationResult.errorCode},errorInfo:${locationResult.errorInfo}".loge()
                }
            }
        }
    }

    private val endChangeReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val action = intent?.action
            "接收结束广播--$action".logi()
            if (action == RECEIVER_SIGNING_END_ACTION) {
                timeUtils?.stop()
                finish()
            }
        }
    }

}
